home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-10-12 | 8.7 KB | 351 lines | [TEXT/R*ch] |
- This is the source text from David Simmons' "Implementing Elegant Drag and Drop
- for Styled Text Fields" article. It's a bit choppy, but may save some typing for
- folks who want to try out parts of it.
-
- TEField[i]dragEnter
-
- “Validate whether the package is interesting”
- (Mouse dragPackageDetect:
- [:type | (type isKindOf: String class)])
- ifFalse: [^self].
-
- ---
-
- “Compute the drag area and then display it”
- outer := self contentBounds asRegion copy insetBy: (-1 @ -1).
- inner := outer copy insetBy: 2.
- outer differenceWith: inner.
-
- ---
-
- Mouse showDragHiliteRegion: outer.
-
- ---
-
- “Indicate that we are tracking the drag operation, but that
- it needs initialization.”
- Mouse dragTargetData: false.
-
- ---
-
- TEField[i]dragExit
- (data := Mouse dragTargetData) ifTrue:
- [
- “Hide any visible blinking bar we may have showing”
- (data at: 6) value: false.
- ].
-
- ---
-
- ^super dragExit
-
- ---
-
- #dragEnter
- #dragWithin “1 or more times depending on whether the
- Mouse moves inside of the field”
- #dragExit
-
- ---
-
- TEField[i]dragWithin
-
- | bottom offset point line localPosition height top data |
-
- ---
-
- data := (Mouse dragTargetData) ? [^self].
-
- ---
-
- “Compute the offset into the text field”
- offset := self offsetOfPoint:
- (localPosition := Mouse localPosition).
-
- ---
-
- data ifFalse:
- [
-
- line := self lineAtOffset: offset.
- point := self pointAtOffset: offset.
- height := self heightFromLine: line to: line.
- bottom := point - (1@0).
- top := (bottom - (0@height)).
-
- data :=
- {
- false. "Not Visible"
- offset. "old offset"
- top. "top"
- bottom. "bottom"
- self hiliteRegion. "The hilited text region"
- [:doShow |
- ((data at: 1) = doShow) ifFalse:
- [
- “Draw in XOR mode”
- activeCanvas
- pushPen;
- penMode: #patXor;
- movePenTo: (data@3);
- drawLineTo: (data@4);
- popPen.
-
- “Update to reflect current state”
- data at: 1 put: doShow.
- ].
- ].
- }.
-
-
- Mouse dragTargetData: data.
-
-
- ].
-
-
- “If the mouse is inside the hilited selection, then hide
- the caret”
- ((Mouse dragInitiator == self)
- and: [(data at: 5) containsPoint: localPosition]) ifTrue:
- [
- ^(data at: 6) value: false
- ].
-
-
- “If it hasn't changed then just toggle/blink the vertical bar”
- (offset = (data at: 2)) ifTrue:
- [
- “Re-draw, toggling the visibility”
- (data at: 6) value:
- ((Clock ticks // Gestalt DoubleTime) isEven).
- ]
-
- “Otherwise, erase the old position and recalculate”
- ifFalse:
- [
- “Erase the old position”
- (data at: 6) value: false.
-
- line := self lineAtOffset: offset.
- point := self pointAtOffset: offset.
- height := self heightFromLine: line to: line.
- bottom := point - (1@0).
- top := (bottom - (0@height)).
-
- data
- at: 2 put: offset;
- at: 3 put: top;
- at: 4 put: bottom.
-
- “Re-draw, toggling the visibility”
- (data at: 6) value: true.
- ].
-
-
- TEField[i]dragItemDropped
-
- | selEnd offset dropPoint dragData selStart result |
-
-
- “Grab the target data, if any”
- (dragData := Mouse dragTargetData) ? [^self dragExit].
-
- dropPoint := Mouse localPosition.
- offset := dragData at: 2.
-
- self dragExit.
-
- “If we were the drag initiator, and the drop was inside our
- hilited text, then do nothing.”
- (Mouse dragInitiator == self
- and: [((Mouse dragInitiatorData@1) & 0x44) not
- and: [Keyboard AltKey not]]) ifTrue:
- [
-
-
- ((dragData@5) containsPoint: dropPoint) ifTrue:
- [
- ^self
- ].
-
- selEnd := self selectionEnd.
- selStart := self selectionStart.
-
- (selEnd ≥ selStart) ifTrue:
- [
- | line height point |
-
-
- line := self lineAtOffset: offset.
- height := self heightFromLine: line to: line.
- point := self pointAtOffset: offset.
-
- “If on the same line then remove the width from
- the offset because it will be cut anyway.”
- ((offset ≥ selStart)
- and: [(self lineAtOffset: selStart) = line])
- ifTrue:
- [
- point := point - (((dragData@5) bounds
- width + 1)@height).
- ] ifFalse:
- [
- point := point - (1@height).
- ].
-
- “Animate the move operation”
- (dragData@5)
- zoomBy: (point - ((dragData@5) bounds origin))
- mode: 1
- steps: 12
- rate: 12.
-
- “Clear the existing selection”
- self doClear.
-
- “Adjust for the portion we remove”
- (selEnd ≤ offset) ifTrue:
- [
- offset := offset - (selEnd - selStart).
- ].
- ].
-
- “Select the insertion point”
- self selectFrom: offset+1 to: offset.
-
- ] ifFalse:
- [
- “Revise the insertion point”
- self selectFrom: offset+1 to: offset.
- ].
-
- “Insert the data”
- Mouse dragItemsDo:
- [:index :typeList | mapType |
-
-
- mapType := nil.
- (typeList includes: Text) ifTrue:
- [
- mapType := Text
- ]
- ifFalse:
- ifFalse:
- [
- (typeList includes: String) ifTrue:
- [mapType := String].
- ].
-
-
- mapType ifTrue:
- [
- result ifNil:
- [
- result := Mouse
- extractDragItem: index
- asInstanceOf: mapType.
- ] ifNotNil:
- [
- result := result,(Mouse
- extractDragItem: index
- asInstanceOf: mapType).
- ].
- ].
-
-
- ].
-
- result ? [^self].
-
-
- self
- nextPutAll: result;
- selectFrom: offset to: offset+ result size.
-
-
- TEField[i]buttonPress: event
- ... Portions Deleted ...
-
- (Switch new)
- case: 1 do:
- [
- (self handleDragEvent: event) ifFalse:
- [
- <<TEClick(localWhere:long;
- (event ShiftKeyOnly):Boolean; self:Handle)>>.
- ].
- ];
-
- ... Portions Deleted ...
-
- on: event clickCount.
-
- self
- updateScrollers;
- "scrollSelectionIntoView;"
- privateSetCursor.
-
- canvas popPen.
- thread popCanvas.
-
-
- TEField[i]handleDragEvent: event
-
- “Implement the drag drop defaults”
- ((self->selStart) ≠ (self->selEnd)) ifTrue:
- [
- | dragRegion |
-
- ((dragRegion := self hiliteRegion)
- containsPoint: (event localWhere)) ifTrue:
- [
-
- [(Mouse isButton1Down) and:
- [(Mouse localWhere maxDelta: event localWhere)
- ≤ 2]] whileTrue.
-
- Mouse isButton1Down ifTrue:
- [
- Mouse
- drag: {self selectedContents}
- withImage: (dragRegion copy differenceWith:
- (dragRegion copy insetBy: 1))
- startingFrom: event localWhere
- initiator: self
- initiatorData:
- {Keyboard metakeys. dragRegion}
-
- “Don't block initial hilite and don't
- auto-center”
- flags: 0x03.
- ^true
-
- ].
- ].
- ].
- ^false
-
-
- Mouse Drag Flag Definitions
-
- 0x0001 .. Do not initially hilite the drag-source
- component
- 0x0002 .. Do not auto-center the drag-image
- 0x0010 .. Restrict dragging to the source Environment
- 0x0020 .. Restrict dragging to the source Module
- 0x0040 .. Restrict dragging to the source Window”
-
- The author can be reached at “David_Simmons@qks.com”. The electronic mail address
- “info@qks.com” is available for any product questions you might have. For more
- general information on SmalltalkAgents you can access:
-
- WorldWideWeb:
- The QKS World Wide Web site “http://www.qks.com/”.
- INTERNET:
- Anonymous ftp via “ftp.qks.com”.
- Compuserve:
- “Go Smalltalk”
- or “Go MacDev [Dynamic Languages Section]”
- or “Go MacDev [Object Oriented Section]”.
-